<template>
  <div class="article-div">
    <!-- 卡片 -->
    <el-card class="article-container">
      <!-- 按钮 -->
      <el-row>
        <el-col :span="8">
          <el-button
            type="danger"
            size="mini"
            icon="el-icon-delete"
            :disabled="!multipleSelection.length"
            @click="handleDel"
            >批量删除</el-button
          >
          <el-button
            size="mini"
            type="primary"
            icon="el-icon-plus"
            @click="handleAdd"
            >添加</el-button
          >
        </el-col>
        <el-col :span="16">
          <span class="title">分类名称</span>
          <el-select
            style="width: 130px; margin: 0 10px"
            size="small"
            v-model="categoryId"
            filterable
            clearable
            reserve-keyword
            @change="handleFind"
            placeholder="请选择分类"
          >
            <el-option
              v-for="item in category"
              :key="item.id"
              :label="item.name"
              :value="item.id"
            />
          </el-select>

          <span class="title">文章名称</span>
          <el-input
            v-model="name"
            size="small"
            placeholder="请输入文章名称"
          ></el-input>

          <el-button
            type="primary"
            size="mini"
            icon="el-icon-search"
            @click="handleFind"
            >查找</el-button
          >
          <el-button
            type="success"
            icon="el-icon-refresh"
            size="mini"
            @click="resetQuery"
            >重置</el-button
          >
        </el-col>
      </el-row>
      <!-- 表格 -->
      <el-table
        border
        height="550px"
        stripe
        fit
        :data="articleList"
        :header-cell-style="{ background: '#F5F7FA', color: '#909399' }"
        :cell-style="centerStyle"
        style="width: 100%"
        @selection-change="handleSelectionChange"
        :default-sort="{
          prop: 'article_createdTime,article_updatedTime',
          order: 'descending',
        }"
      >
        <el-table-column type="selection"></el-table-column>
        <el-table-column label="id" prop="id" width="47px"></el-table-column>
        <el-table-column label="文章封面" width="170px">
          <template slot-scope="article">
            <el-avatar
              shape="square"
              :src="
                article.row.article_pic == null || article.row.article_pic == ''
                  ? '/article_pic.webp'
                  : baseUrl + article.row.article_pic
              "
            ></el-avatar>
          </template>
        </el-table-column>
        <el-table-column label="文章名称" prop="article_title" width="200px">
        </el-table-column>
        <el-table-column label="分类" width="100px">
          <template slot-scope="article"
            ><el-tag type="warning">{{ article.row.name }}</el-tag></template
          >
        </el-table-column>
        <el-table-column label="浏览量" prop="article_views"> </el-table-column>
        <el-table-column label="点赞量" prop="article_praise">
        </el-table-column>
        <el-table-column
          label="添加时间"
          width="185px"
          prop="article_createdTime"
          sortable
        >
          <template slot-scope="article">
            <i class="el-icon-time"></i>
            <span style="margin-left: 10px">{{
              article.row.article_createdTime
            }}</span>
          </template>
        </el-table-column>
        <el-table-column
          label="更新时间"
          width="185px"
          prop="article_updatedTime"
          sortable
        >
          <template slot-scope="article">
            <i class="el-icon-time"></i>
            <span style="margin-left: 10px">{{
              article.row.article_updatedTime
            }}</span>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="160px">
          <template v-slot="rowInfo">
            <el-button
              type="primary"
              size="mini"
              icon="el-icon-edit"
              style="padding: 7px 10px"
              @click="handleUpdate(rowInfo.row.id)"
              >编辑</el-button
            >
            <el-button
              type="danger"
              size="mini"
              icon="el-icon-delete"
              style="padding: 7px 10px"
              @click="handleDel(rowInfo.row)"
              >删除</el-button
            >
          </template>
        </el-table-column>
      </el-table>
      <!-- 分页器 -->
      <div
        class="pagination-container"
        style="float: right; margin-bottom: 15px; margin-top: 15px"
      >
        <el-pagination
          background
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          :current-page="page"
          :page-sizes="[1, 3, 5, 10]"
          :page-size="size"
          layout="total, sizes, prev, pager, next, jumper"
          :total="total"
        >
        </el-pagination>
      </div>
    </el-card>
    <!-- 全屏弹框 -->
    <el-dialog
      :title="flag == 0 ? '添加文章' : '修改文章'"
      :visible.sync="centerDialogVisible"
      center
      fullscreen
      :before-close="closeBeforeDialog"
    >
      <el-form ref="dataForm" :model="article" :rules="rules">
        <el-row style="margin-bottom: 30px">
          <el-col :span="12">
            <el-form-item
              label="文章名称"
              label-width="100px"
              prop="title"
              style="margin: 0 0 30px"
            >
              <el-input v-model="article.title" style="width: 400px"></el-input>
            </el-form-item>
            <el-form-item label="文章分类" label-width="100px" prop="name">
              <el-tag
                type="success"
                v-show="article.name"
                style="margin: 0 10px 0 0"
                closable
                :disable-transitions="false"
                @close="removeCategory"
              >
                {{ article.name }}
              </el-tag>
              <!-- 分类选项 popover弹框-->
              <el-popover
                placement="bottom-start"
                width="400"
                trigger="click"
                v-if="!article.name"
              >
                <div style="margin-bottom: 10px">分类</div>
                <el-input
                  style="width: 100%"
                  v-model="categoryName"
                  placeholder="请输入分类名,回车添加分类"
                  @keyup.enter.native="addCategory"
                ></el-input>
                <!-- 具体分类 -->
                <div class="prop-container">
                  <div style="margin: 10px 0">添加分类</div>
                  <el-tag
                    style="cursor: pointer; margin: 0 3px"
                    v-for="(item, index) in category"
                    :key="index"
                    class="category-item"
                    @click="addCategory_1(item)"
                  >
                    {{ item.name }}
                  </el-tag>
                </div>
                <el-button type="success" slot="reference" size="small">
                  添加分类
                </el-button>
              </el-popover>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item
              label="文章封面"
              label-width="100px"
              style="margin-left: 164px"
            >
              <el-upload
                class="avatar-uploader"
                action=" "
                :show-file-list="false"
                :before-upload="beforeAvatarUpload"
                :auto-upload="false"
                drag
                :on-change="handlePicChange"
                ref="uploadPic"
              >
                <img
                  v-if="article.imageUrl"
                  :src="article.imageUrl"
                  class="avatar"
                />
                <i v-else class="el-icon-plus avatar-uploader-icon"></i>
              </el-upload>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item label="文章内容" label-width="100px" prop="mdContent">
              <mavon-editor
                ref="md"
                :codeStyle="codeStyle"
                placeholder="请输入文章内容"
                :ishljs="true"
                v-model="article.mdContent"
                style="height: 600px; width: 100%"
                @imgAdd="imgAdd"
                @imgDel="imgDel"
              >
              </mavon-editor>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="centerDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="submit">确定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import axios from "axios";
export default {
  name: "Article",
  data() {
    return {
      articleList: [],
      size: 5, //每页显示条数
      page: 1, // 当前页码
      total: 0, //总记录数
      baseUrl: "http://localhost:3000/", //后端地址
      formLabelWidth: "100px", //label宽度
      id: 1, //保存登录id
      id_update: 0, //保存修改文章id
      name: "", //搜索框内容
      multipleSelection: [],
      category: [],
      categoryId: null,
      article: {
        title: "",
        name: "",
        mdContent: "",
        content: "",
        imageUrl: "",
      },
      title: "", // 大标题
      centerDialogVisible: false,
      flag: 0, //0 代表添加,1 代表编辑
      categoryName: "", //保存分类名
      codeStyle: "monokai-sublime",
      // confirm: false,
      picList: [], //保存上传文件
      img_file: {}, //缓存上传图片文件
      token: {}, //七牛云token
      domain: "https://upload-z2.qiniup.com", //七牛云的上传地址,
      qiniuaddr: "rjmxquwfx.hn-bkt.clouddn.com", //七牛云外链地址
      rules: {
        title: [{ required: true, message: "必填字段", trigger: "blur" }],
        name: [{ required: true, message: "必填字段", trigger: "blur" }],
        mdContent: [{ required: true, message: "必填字段", trigger: "blur" }],
      },
    };
  },
  created() {
    this.id = sessionStorage.getItem("id");
    this.getArticles();
    this.getCategoryList();
  },
  methods: {
    // 表格内容居中统一样式
    centerStyle() {
      return "text-align:center";
    },
    // 获取全部文章
    getArticles() {
      // GET /users/getArticles?page=1&size=4
      this.$http
        .get("/article/getArticle", {
          params: {
            page: this.page,
            size: this.size,
            article_title: this.name,
            categoryId: this.categoryId,
          },
        })
        .then((res) => {
          if (res.code == 0) {
            // console.log(res.result);
            this.articleList = res.result.rows;
            this.total = res.result.total;
          }
        });
    },
    // 获取分类列表
    getCategoryList() {
      this.$http.get("/category/getName").then((res) => {
        if (res.code == 0) {
          // console.log(res.result);
          this.category = res.result;
        }
      });
    },
    // 改变条数时,执行回调
    handleSizeChange(size) {
      this.size = size;
      // 发请求
      this.getArticles();
    },
    // 改变当前页码,执行回调
    handleCurrentChange(page) {
      this.page = page;
      this.getArticles();
    },
    // 删除文章
    handleDel(row) {
      this.$confirm("此操作将永久删除该文章, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          // console.log(row.id);
          let ids = [];
          if (row.id) {
            ids.push(row.id);
          } else {
            this.multipleSelection.forEach((item) => {
              ids.push(item.id);
            });
          }
          this.$http
            .delete(`/article/deleted`, { data: { ids } })
            .then((res) => {
              if (res.code == 0) {
                this.getArticles();
                this.$message({
                  type: "success",
                  message: "删除成功!",
                });
              }
            });
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "已取消删除",
          });
        });
    },
    //按文章名称查找文章
    handleFind() {
      if (this.name != "" && this.categoryId == null) {
        this.getArticles();
        this.name = "";
      } else if (this.categoryId !== null) {
        this.getArticles();
        this.name = "";
        this.categoryId = null;
      } else {
        this.$message.error("搜索名称不能为空!");
      }
    },
    // 重置表格
    resetQuery() {
      this.name = "";
      this.categoryId = null;
      this.getArticles();
    },
    // 选择改变时回调
    handleSelectionChange(val) {
      this.multipleSelection = val;
    },
    // 添加按钮
    handleAdd() {
      let article = sessionStorage.getItem("article");
      // console.log(article);
      if (article != null) {
        this.$confirm("有未完成的文章,是否继续编辑?", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        })
          .then(() => {
            this.article = JSON.parse(article);
            // this.flag = 0;
            this.centerDialogVisible = true;
          })
          .catch(() => {
            for (let key in this.article) {
              this.article[key] = "";
            }
            this.flag = 0;
            sessionStorage.removeItem("article");
            this.centerDialogVisible = true;
          });
      } else {
        for (let key in this.article) {
          this.article[key] = "";
        }
        this.flag = 0;
        this.centerDialogVisible = true;
      }
    },
    // 编辑按钮
    handleUpdate(id) {
      // 清空article
      this.id_update = id;
      for (let i in this.article) {
        this.article[i] = "";
      }
      this.$http.get(`/article/getSingleArt/${id}`).then((res) => {
        if (res.code == 0) {
          // 回显数据
          const { article_title, article_content, name, article_pic } =
            res.result;
          this.article.title = article_title;
          this.article.mdContent = article_content;
          this.article.name = name;
          this.article.imageUrl = this.baseUrl + article_pic;
          // 控制标题
          this.flag = 1;
          // 显示弹框
          this.centerDialogVisible = true;
        }
      });
    },
    // 关闭标签回调
    removeCategory() {
      this.article.name = "";
    },
    // 回车添加分类名
    addCategory() {
      this.article.name = this.categoryName;
      this.categoryName = "";
    },
    // 选择添加分类
    addCategory_1(item) {
      this.article.name = item.name;
    },
    // 上传文件之前回调,判断文件大小和类型
    beforeAvatarUpload(file) {
      const isJPG = file.type === "image/jpeg" || file.type === "image/png";
      const isLt2M = file.size / 1024 / 1024 < 2;

      if (!isJPG) {
        this.$message.error("上传封面图片只能是 JPG/PNG 格式!");
      }
      if (!isLt2M) {
        this.$message.error("上传封面图片大小不能超过 2MB!");
      }
      return isJPG && isLt2M;
    },
    // 上传文件成功的回调
    handlePicChange(file) {
      // console.log(file.raw);
      this.article.imageUrl = URL.createObjectURL(file.raw);
      // 把上传文件添加到dataList
      this.picList.push(file.raw);
    },
    // 关闭弹框前的回调
    closeBeforeDialog(done) {
      if (
        this.article.title != "" ||
        this.article.name != "" ||
        this.article.mdContent != "" ||
        this.article.imageUrl != ""
      ) {
        this.$confirm("是否退出编辑?", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        })
          .then(() => {
            sessionStorage.setItem("article", JSON.stringify(this.article));
            done(); //关闭弹框
          })
          .catch(() => {
            this.$message({
              type: "info",
              message: "已取消",
            });
          });
      } else {
        done(); //关闭弹框
      }
    },
    //获得图片名
    getFileName($file) {
      let filetype = "";
      if ($file.type == "image/png") {
        filetype = "png";
      } else {
        filetype = "jpg";
      }
      // console.log($file);
      const keyname =
        "image-wsh_" +
        $file.name.substring(0, $file.name.indexOf(".")) +
        "_" +
        new Date().getTime() +
        "." +
        filetype;
      return keyname;
    },
    // mavon编辑器缓存上传图片文件
    imgAdd(pos, $file) {
      const keyname = this.getFileName($file);
      // 获取七牛云token
      this.$http.get("/token").then((res) => {
        // console.log(res);
        // 上传图片到服务器
        const formData = new FormData();
        formData.append("file", $file);
        formData.append("token", res);
        formData.append("key", `public/${keyname}`);

        // 上传文件到七牛云空间
        axios
          .post(this.domain, formData, {
            headers: {
              "Content-Type": "multipart/form-data",
            },
          })
          .then((res) => {
            // console.log(res.data.key);
            const imgUrl = `http://${this.qiniuaddr}/${res.data.key}`;
            this.$refs.md.$img2Url(pos, imgUrl);
          });
      });
    },
    //  mavon 删除图片文件
    imgDel(filename) {
      // console.log(filename);
      const arr = filename[0].split("/");
      const key = `public/${arr.slice(-1)}`;
      // console.log(key);
      this.$http.post("/qiniuDel", { key }).then((res) => {
        if (res.code == 0) {
          console.log("删除图片成功");
        }
      });
    },
    // 添加文章
    addArticle() {
      this.$http.post("/article/add", this.article).then((res) => {
        if (res.code == 0) {
          let msg = res.msg;
          const id = res.result.id;
          const formData = new FormData();
          // 把封面添加到form对象中
          formData.append("coverPic", this.picList[0]);
          this.$http
            .post(`/article/uploadPic/${id}`, formData, {
              headers: {
                "Content-Type": "multipart/form-data",
              },
            })
            .then((res) => {
              if (res.code == 0) {
                // this.article.imageUrl = this.baseUrl+res.result.article_pic;
                // this.confirm = true;
                this.getArticles();
                this.centerDialogVisible = false;
                this.$message.success(msg);
              }
            });
        }
      });
    },
    // 修改文章
    updateArticle() {
      this.$http
        .put(`/article/update/${this.id_update}`, this.article)
        .then((res) => {
          if (res.code == 0) {
            let msg = res.msg;
            const formData = new FormData();
            // 把封面添加到form对象中
            formData.append("coverPic", this.picList[0]);
            this.$http
              .put(`/article/updatePic/${this.id_update}`, formData, {
                headers: {
                  "Content-Type": "multipart/form-data",
                },
              })
              .then((res) => {
                if (res.code == 0) {
                  // this.confirm = true;
                  this.getArticles();
                  this.centerDialogVisible = false;
                  this.$message.success(msg);
                }
              });
          }
        });
    },
    // 提交文章
    submit() {
      this.$refs.dataForm.validate((valid) => {
        if (valid) {
          // console.log(this.$refs.md.d_render)
          this.article.content = this.$refs.md.d_render;
          // 添加文章
          if (this.flag == 0) {
            this.addArticle();
          } else {
            // 修改文章
            this.updateArticle();
          }
        } else {
          this.$message.error("存在必填字段未填");
        }
      });
    },
  },
};
</script>

<style lang="stylus">
.article-div
  .el-dialog
    .el-dialog__header
      margin-bottom:20px
      &>span
        font-size: 25px
        font-weight:bold
</style>
<style lang="stylus" scoped>
.article-div
  user-select: none
  .article-container
    margin-top: 20px
    min-height: 400px
    .el-col
      .title
        font-size:14px
        font-weight:700
        color: #606266
        margin-left: 48px
      .el-input
        width: 38%
        margin-right: 10px
        margin-left: 10px
      .el-button
        padding:7px 10px
    .el-table
      margin-top: 30px
      &>>>th.el-table__cell>.cell
        text-align: center
        font-weight:bold
      &>>>.el-avatar
        width: 145px
        height: 80px
        img
          width: 150px
  .el-dialog
    .el-form-item
      &>label
        font-weight:bold
    .avatar-uploader
      &>>>.el-upload
        width 178px
        height:178px
        margin-left: 22px
        border:1px dashed #d9d9d9
        border-radius:6px
        cursor: pointer
        position: relative;
        overflow: hidden;
        &:hover
          border-color: #409EFF
        .el-upload-dragger
          width:178px
        .avatar-uploader-icon
          font-size: 28px
          color: #8c939d
          width: 178px
          height: 178px
          line-height: 178px
          text-align: center
        .avatar
          width: 178px
          height: 178px
          display: block
</style>
